$(function() {
	/* sprints */
	var sprint_name = $("#sprint-name" ),
	    sprint_description = $("#sprint-description"),
		sprint_start_date = $("#sprint-start-date"),
		sprint_end_date = $("#sprint-end-date"),
		all_sprint_fields = $([]).add(sprint_name).add(sprint_description).add(sprint_start_date).add(sprint_end_date),
		sprint_tips = $(".sprintValidateTips"),
		sprintValidateText = "All fields are required.";
	
	var cancelSprintButtonText = "Cancel Sprint";
	var deleteSprintButtonText = "Delete";
    
    $("p.sprintValidateTips").text(sprintValidateText);
    
	$.getJSON("SprintView").done(function(result) {
		$.each(result.row, function(i, row) {
			appendDataToSprint(row);
		});

		ProperlyDisplaySprintButtons();
	}).fail(function() {
		alert('Error loading sprint data');
	});

	function ProperlyDisplaySprintButtons() {	
		if (sessionRoleName != "Product Owner") {
			$(".cancel-sprint-button").hide();
			$(".delete-sprint-button").show();
		}
	}
	
	// hide Add new sprint button if user is not assigned a project
	if (sessionProjectId == 0) {
		$("#add-sprint").hide();
		$("h2").hide();
	}

	function getDate(dateString) {
		var dateComponents = dateString.split("-");
		var year = dateComponents[0];
		var month = parseInt(dateComponents[1]) - 1;
		var day = dateComponents[2];

		return new Date(year, month, day);
	}
	
	function zeropadDateDigits(str) {
		return ("0" + str).slice(-2);
	}
	
	function isTodayInSprintRange(row) {
		var today = new Date();
		var todayString = today.getFullYear()
			+ "-" + zeropadDateDigits(today.getMonth() + 1)
			+ "-" + zeropadDateDigits(today.getDate());
		
		return (row.start_date <= todayString && row.end_date >= todayString);
	}

	function getSprintHtml(row) {
		if (isTodayInSprintRange(row)) {
			buttonHtml = '<button class="cancel-sprint-button">' + cancelSprintButtonText + '</button>\n';
		}
		else {
			buttonHtml = '<button class="delete-sprint-button">' + deleteSprintButtonText + '</button>\n';
		}
		
		return '<div id="sprint-' + row.sprint_id + '" class="sprint">\n'
		+ '<button class="edit-sprint-button">Edit</button>\n'
		+ buttonHtml
		+ '<h3>(<span class="start_date">' + row.start_date + '</span> - <span class="end_date">' + row.end_date
		+ '</span>)<br><span class="this-sprint-name">' + row.name + '</span></h3>\n'
		+ '<ul id="sprint-' + row.sprint_id + '-list" class="sortable-list ui-sortable">\n';
	}
	
	function appendDataToSprint(row) {
		$("#sprints").append(getSprintHtml(row));

		for (var i = 0; i < row.user_story.length; i++) {
			appendDataToBacklog("sprint-" + row.sprint_id  + "-list", row.user_story[i]);
		}

		$("#sprints").append('</ul>\n</div>');

		$('#content .sortable-list').sortable(sortableFunctions);
	}
	
	/* sprint dialog box */
 
    function closeProjectDialogBox(dialogBox) {
		all_sprint_fields.val("").removeClass("ui-state-error");
		all_sprint_fields.val("");
		$("p.sprintValidateTips").text(sprintValidateText);
	    $(dialogBox).dialog("close");
    }
    
	$.datepicker.setDefaults({
		dateFormat: 'yy-mm-dd',
		showOn: "button",
		buttonImage: "http://jqueryui.com/resources/demos/datepicker/images/calendar.gif",
		buttonImageOnly: true
	});
	
	$("#sprint-start-date").datepicker();
	$("#sprint-end-date").datepicker();
	
	$('#sprint-start-date').attr("readonly", true);
	$('#sprint-end-date').attr("readonly", true);
	
	$("#add-sprint").button().click(function() {
		$("#sprint-dialog-form").dialog('option', 'title', 'Add new sprint');
		$("#sprint-dialog-form").dialog({
			buttons : {
				"Add" : function() {
					if (validateSprintData(sprint_name, sprint_description, sprint_start_date, sprint_end_date, sprint_tips, "", "")) {
						$.post("AddSprint", $("#sprint-form").serialize()).done(function( data ) {
							var returned_data = jQuery.parseJSON(data);
							
							addNewSprint(returned_data);
						}).fail(function() {
							alert('Error adding sprint');
						});

						$(this).dialog("close");
					}
				}
			},
			close : function() {
				closeProjectDialogBox(this);
			}
		});
		$("#sprint-dialog-form").dialog("open");

	});
	
	function addNewSprint(row) {
		var foundALocation = false;
		
		$.each($('.start_date'), function (index, value) {
			// if start date in dialog box is after this date
			if ($(this).text() < row.start_date) {
				foundALocation = true;

				$(this).parent().parent().before(getSprintHtml(row));
				$('#content .sortable-list').sortable(sortableFunctions);
				
				return false;	// break out of loop
			}
		});

		// if not found, append to bottom of the list
		if (! foundALocation) {
			appendDataToSprint(row);
		}

		ProperlyDisplaySprintButtons();
	}
	
	function repositionSprint(row) {
		var foundALocation = false;
		var sprintId = 0;
		
		$.each($('.start_date'), function (index, value) {
			sprintId = $(this).parent().parent().attr('id');
			// if start date in dialog box is after this date
			if ($(this).text() < row.start_date) {
				foundALocation = true;
				$('#sprint-' + row.sprint_id).insertBefore($(this).parent().parent());
				$('#content .sortable-list').sortable(sortableFunctions);
				
				return false;	// break out of loop
			}
		});

		// if not found, append to bottom of the list
		if (! foundALocation) {
			$('#sprint-' + row.sprint_id).insertBefore($('#' + sprintId));
		}
	}

	$("#sprint-dialog-form").dialog({
		autoOpen : false,
		height : 500,
		width : 550,
		modal : true
	});

	function validateSprintData(name, description, start_date, end_date, sprint_tips, original_start_date, original_end_date) {
		var bValid = true;

		all_sprint_fields.removeClass("ui-state-error");
		
		bValid = bValid	&& checkLength(name, "name", 1, 50, sprint_tips);
		bValid = bValid	&& checkLength(description,	"description", 1, 250, sprint_tips);
		
		// check start/end dates
		
		// valid format
		bValid = bValid && checkDateFormat(start_date, "start date", sprint_tips);
		bValid = bValid && checkDateFormat(end_date, "end date", sprint_tips);
		
		// dates at or after current date (?? allow back filling of sprints to be fluid instead ??)
		
		// start date before end date
		bValid = bValid && checkDateOrder(start_date, end_date, sprint_tips);

		// if doing an update (original dates are set)
		if (original_start_date !== "" && original_end_date !== "") {
			// still the same, then skip date range validation?
			if (start_date.val() === original_start_date && end_date.val() === original_end_date) {
				return bValid;
			}
		}
		
		// no overlapping dates from other sprints
		var rangeCheckStatus = checkDateRange(start_date, end_date, sprint_tips,
			original_start_date, original_end_date);
		
		if (! rangeCheckStatus) {
        	// update dialog error notifications
			start_date.addClass("ui-state-error");
			end_date.addClass("ui-state-error");
			updateTips(sprint_tips, "Invalid date range.  Dates overlap with an existing sprint.");
		}

		bValid = bValid && rangeCheckStatus;

		return bValid;
	}
	
	function checkDateFormat(date, name, tips) {
		if (date.val().match('[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]') == null) { 
			date.addClass("ui-state-error");
			updateTips(tips, "Invalid date format for " + name);
			return false;
		}
		else {
			return true;
		}
	}
	
	function checkDateOrder(start_date, end_date, tips) {
		if (end_date.val() <= start_date.val()) {
			end_date.addClass("ui-state-error");
			updateTips(tips, "End date needs to be after start date.");
			return false;
		}
		else {
			return true;
		}
	}
	
	function checkDateRange(start_date, end_date, tips, original_start_date, original_end_date) {
		// create an array of start and end dates
		var start_dates = $(".start_date").map(function(){return $(this);}).get();
		var end_dates = $(".end_date").map(function(){return $(this);}).get();
		
		// determine earliest start date and latest end date
		
		var earliestStartDate = "";
		var latestEndDate = "";
		var status = true;
		$.each(end_dates, function(i, value) {
			// if updating, skip the original dates
			if (start_dates[i].text() === original_start_date && value.text() === original_end_date) {
				return true;	// continue
			}
			
			if (earliestStartDate === "" || start_dates[i].text().localeCompare(earliestStartDate) < 0) {
				earliestStartDate = start_dates[i].text();
			}

			if (latestEndDate === "" || value.text().localeCompare(latestEndDate) < 0) {
				latestEndDate = value.text();
			}

			// determine if start and end dates are within an existing range

			if (start_date.val().localeCompare(start_dates[i].text()) >= 0 && start_date.val().localeCompare(value.text()) <= 0) {
				status = false;
				return false;	// break
			}
			
			if (end_date.val().localeCompare(start_dates[i].text()) >= 0 && end_date.val().localeCompare(value.text()) <= 0) {
				status = false;
				return false;	// break
			}
		});

		if (status === false) {
			return false;
		}
		
		// check if outside of entire range
		
		if (start_date.val().localeCompare(earliestStartDate) < 0 && end_date.val().localeCompare(latestEndDate) > 0) {
			return false;
		}
		
		// TODO check if one is outside entire range and one is inside another's range
		return true;
	}
	
	/* edit sprint */
	
	$(document).on("click", ".edit-sprint-button", function() {
		var sprint_id = $(this).closest('div').closest('div').attr('id').match(/[\d]+/);
		var parameters = "sprint-id=" + sprint_id;
		var returned_data = "";
	
		$.post("GetSprintData", parameters).done(function(data) {
			returned_data = jQuery.parseJSON(data);

			$("#sprint-dialog-form").data('sprint-id', returned_data.sprint_id);
			$("#sprint-dialog-form").data('start-date', returned_data.start_date);
			$("#sprint-dialog-form").data('end-date', returned_data.end_date);
			$("#sprint-name").val(returned_data.name);
			$("#sprint-description").val(returned_data.description);
			$("#sprint-start-date").val(returned_data.start_date);
			$("#sprint-end-date").val(returned_data.end_date);
		}).fail(function() {
			alert('Error getting sprint data');
		});
		
		$("#sprint-dialog-form").dialog('option', 'title', 'Edit sprint id ' + $(this).closest('div').attr('id').match(/[\d]+/));
		$("#sprint-dialog-form").dialog({
			buttons: {
				"Update" : function() {
					if (validateSprintData(sprint_name, sprint_description,
							sprint_start_date, sprint_end_date, sprint_tips,
							$("#sprint-dialog-form").data('start-date'),
							$("#sprint-dialog-form").data('end-date'))) {
						parameters += "&" + $("#sprint-form").serialize();

						$.post('EditSprint', parameters).done(function(data) {
							returned_data = jQuery.parseJSON(data);
							updateSprint(
								$("#sprint-dialog-form").data('start-date'),
								$("#sprint-dialog-form").data('end-date'),
								returned_data);
							
						}).fail(function() {
							alert('Error updating sprint data');
						});
						
						$(this).dialog("close");
					}
				}
			},
			close : function() {
				closeProjectDialogBox(this);
			}
		});
		
		$("#sprint-dialog-form").dialog("open");

	});
	
	$(document).on("click", ".delete-sprint-button", function() {
		var sprint_id = $(this).closest('div').closest('div').attr('id').match(/[\d]+/);
		var sprint_name = $(this).closest('div').find('.this-sprint-name').text();
		var parameters = "sprint-id=" + sprint_id;
		
		var confirmDelete = confirm('Are you sure you want to delete sprint ' + sprint_name
				+ ' (id '+ sprint_id + ') from the project and its associated user stories, tasks and tests?');
		
		if (confirmDelete != true) return;

		$.post("DeleteSprint", parameters).done(function(data) {
			var returnedData = jQuery.parseJSON(data);
			if (returnedData.status == true) {
				$('#sprint-' + sprint_id).remove();
			}
			else {
				alert("Error deleting " + sprint_name);
			}
		}).fail(function() {
			alert('Error completing deleting a sprint');
		});
	});

	function updateSprint(previous_start_date, previous_end_date, returned_data) {
		// update date range text
		$('#sprint-' + returned_data.sprint_id).children('h3').html(
			'(<span class="start_date">' + returned_data.start_date
					+ '</span> - <span class="end_date">' + returned_data.end_date
					+ '</span>)<br>' + returned_data.name
		);
		
		// if start or end date changed, reposition the sprint
		if (previous_start_date != returned_data.start_date
				|| previous_end_date != returned_data.end_date) {
			
			repositionSprint(returned_data);
		}
		
		// update Delete/Cancel Sprint button
		if (isTodayInSprintRange(returned_data)) {
			var button = $('#sprint-' + returned_data.sprint_id).children('.delete-sprint-button');
			button.html(cancelSprintButtonText);
			button.attr('class', 'cancel-sprint-button');
		}
		else {
			var button = $('#sprint-' + returned_data.sprint_id).children('.cancel-sprint-button');
			button.html(deleteSprintButtonText);
			button.attr('class', 'delete-sprint-button');
		}
		
		ProperlyDisplaySprintButtons();
	}

    // cancel a sprint
    
	$(document).on("click", ".cancel-sprint-button", function() {
		var sprint_id = $(this).closest('div').closest('div').attr('id').match(/[\d]+/);
		var sprint_name = $(this).closest('div').find('.this-sprint-name').text();
		var parameters = "sprint-id=" + sprint_id;
		
		var confirmDelete = confirm('Are you sure you want to cancel sprint ' + sprint_name
				+ ' (id '+ sprint_id + ')?  This will move unfinished user stories to the backlog'
				+ ' and terminate the sprint.');
		
		if (confirmDelete != true) return;

		$.post("CancelSprint", parameters).done(function(data) {
			var returnedData = jQuery.parseJSON(data);
			var answer = confirm("Moved " + returnedData.user_stories_moved_to_backlog + " user stories to the backlog.");
			if (answer) {
				location.reload(true);	// reload page
			}
		}).fail(function() {
			alert('Error completing canceling a sprint');
		});
	});
    
});
